package com.gin.no_gay_alliance.database.manager;

import android.util.Log;
import android.widget.Toast;

import androidx.annotation.IntRange;

import com.gin.nga.client.NgaClient;
import com.gin.nga.enums.NgaDomain;
import com.gin.no_gay_alliance.app.MyApplication;
import com.gin.no_gay_alliance.database.dao.NgaAccountDao;
import com.gin.no_gay_alliance.database.entity.NgaAccount;
import com.gin.no_gay_alliance.utils.DataStoreUtils;

import java.io.IOException;

import okhttp3.OkHttpClient;

/**
 * 账号管理器
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/8/1 17:23
 **/
public class AccountManager {
    private final static String TAG = AccountManager.class.getSimpleName();
    private static final String TEMP_COOKIE = "ngaPassportUid=0; ngaPassportUrlencodedUname=AnonymousUser; ngaPassportCid=aa; ";
    /**
     * 当前账号在Datastore中保存的key
     */
    private static final String DATA_STORE_KEY_CURRENT_USER_ID = "CURRENT_USER_ID";
    private static final String DATA_STORE_KEY_DOMAIN = "DOMAIN";
    private final NgaAccountDao dao;
    private final OkHttpClient okHttpClient;
    private NgaClient client;
    /**
     * 域名
     */
    private NgaDomain domain;

    public AccountManager(NgaAccountDao ngaAccountDao, OkHttpClient okHttpClient) {
        this.dao = ngaAccountDao;
        this.okHttpClient = okHttpClient;

        initDomain();
        // 设置当前账号
        initClient(getCurrentUserId());
    }

    /**
     * 修改域名
     *
     * @param domain 域名
     */
    public void updateDomain(NgaDomain domain) {
        Log.i(TAG, "设置域名:" + domain.domain);
        this.domain = domain;
        DataStoreUtils.getInstance().set(DATA_STORE_KEY_DOMAIN, domain.domain);
        // 重新创建客户端
        try {
            this.client = new NgaClient(this.client.getCookie(), okHttpClient, domain);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 初始化客户端
     */
    public void initClient(long userId) {
        try {
            if (userId > 0) {
                NgaAccount account = dao.listAll().stream().filter(i -> i.userId == userId).findFirst().orElse(null);
                if (account != null) {
                    this.client = new NgaClient(account.cookie, okHttpClient, domain);
                    Toast.makeText(MyApplication.app, "已登陆:" + this.client.getUsername(), Toast.LENGTH_SHORT).show();
                    Log.i(TAG, "已登陆:" + this.client.getUsername());
                } else {
                    Log.w(TAG, "setClient: 未登记的账号信息 uid = " + userId);
                    this.client = new NgaClient(TEMP_COOKIE, okHttpClient, domain);
                }
            } else {
                Toast.makeText(MyApplication.app, "未登陆", Toast.LENGTH_SHORT).show();
                Log.w(TAG, "setClient: 未登陆");
                this.client = new NgaClient(TEMP_COOKIE, okHttpClient, domain);
            }
        } catch (IOException e) {
            Log.w(TAG, "setClient: 设置客户端失败", e);
            Toast.makeText(MyApplication.app, "设置客户端失败", Toast.LENGTH_SHORT).show();
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过cookie添加账号
     *
     * @param cookie cookie
     * @return
     */
    public NgaAccount addAccount(String cookie) {
        try {
            NgaClient newClient = new NgaClient(cookie);
            // 新账号
            NgaAccount newAccount = new NgaAccount();
            newAccount.userId = newClient.getUserId();
            newAccount.username = newClient.getUsername();
            newAccount.cookie = newClient.getCookie();
            dao.add(newAccount);

            return newAccount;
        } catch (IOException e) {
            Log.w(TAG, "addAccount: 添加账号失败", e);
            Toast.makeText(MyApplication.app, "添加账号失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            throw new RuntimeException(e);
        }
    }

    /**
     * 移除账号
     *
     * @param userId 用户id
     */
    public void removeAccount(long userId) {
        dao.delete(userId);

        Log.d(TAG, "移除账号: " + userId);

        // 如果移除的是当前账号，初始化客户端
        if (getCurrentUserId() == userId) {
            DataStoreUtils.getInstance().set(DATA_STORE_KEY_CURRENT_USER_ID, -1L);
            initClient(-1L);
        }
    }

    /**
     * 初始化域名
     */
    private void initDomain() {
        String domain = DataStoreUtils.getInstance().get(DATA_STORE_KEY_DOMAIN, NgaDomain.cn.domain);
        this.domain = NgaDomain.findByValue(domain);
    }

    public NgaClient getClient() {
        return client;
    }

    public long getCurrentUserId() {
        return DataStoreUtils.getInstance().get(DATA_STORE_KEY_CURRENT_USER_ID, -1L);
    }

    public NgaDomain getDomain() {
        return domain;
    }

    /**
     * 判断是否已登陆
     *
     * @return 是否已登陆
     */
    public boolean isLogged() {
        return client != null && client.getUserId() > 0;
    }

    /**
     * 设置当前用户
     *
     * @param userId 用户id
     */
    public void setCurrentUser(@IntRange(from = 1) long userId) {
        DataStoreUtils.getInstance().set(DATA_STORE_KEY_CURRENT_USER_ID, userId);
        initClient(userId);
        // 重新加载提醒消息
        MyApplication.app.managerFactory.getNoticeManager().onAccountChanged();
        // 清除内存缓存
        MyApplication.app.managerFactory.getBlockDataManager().clear();
    }
}
